home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 22 / PC Actual CD 22.iso / SHARE / wnt / adnm / ADMNALOW.C next >
Encoding:
C/C++ Source or Header  |  1997-03-24  |  13.5 KB  |  484 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <locale.h>
  4.  
  5. // Modified to use hard-coded SID
  6.  
  7. // Unicode constants
  8. WCHAR* DOT;
  9. WCHAR* DOTDOT;
  10. WCHAR* BACKSLASH;
  11. WCHAR* SDS;
  12. PSID adminSid;
  13. SECURITY_DESCRIPTOR adminOwner;
  14. PACCESS_ALLOWED_ACE fileAllowAce;
  15. PACCESS_ALLOWED_ACE dirAllowAce1;
  16. PACCESS_ALLOWED_ACE dirAllowAce2;
  17.  
  18. WCHAR* lmbstowcs(char* aname);
  19. void printerror(char* str,WCHAR* file,DWORD errorno);
  20. void recursive_find(WCHAR* searchpath);
  21. void setConstants(void);
  22. void processFile(WCHAR* file,BOOL isDir);
  23. void getPrivs(void);
  24. DWORD getFileSecurity(WCHAR* file,PSECURITY_DESCRIPTOR* desc);
  25. HLOCAL SafeAlloc(UINT bytes);
  26. BOOL isAclOkay(WCHAR* file,PSECURITY_DESCRIPTOR desc,BOOL isDir);
  27. void AddAdminPerms(WCHAR* file,BOOL isDir);
  28.  
  29. int main(int argc,char* argv[])
  30. {
  31. WCHAR* searchPath;
  32. int i;
  33. if(argc<2) {
  34.   printf("Admin Allow gives administrators full access to NTFS files.\n");
  35.   printf("It does not otherwise disturb existing permissions.\n");
  36.   printf("Usage:   %s path1 path2\n",argv[0]);
  37.   printf("Example: %s d: e:\\users\n",argv[0]);
  38.   printf("V1.02 Mar 24 '97 Mike Ingle (inglem@adnetsol.com)\n");
  39.   exit(1);
  40.   }
  41. setConstants();
  42. getPrivs();
  43. for(i=1;i<argc;i++) {
  44.   searchPath=lmbstowcs(argv[i]);
  45.   recursive_find(searchPath);
  46.   LocalFree(searchPath);
  47.   }
  48. return(0);
  49. }
  50.  
  51. // Check for admin all access
  52. BOOL isAclOkay(WCHAR* file,PSECURITY_DESCRIPTOR desc,BOOL isDir)
  53. {
  54. BOOL daclPresent;
  55. PACL acl;
  56. BOOL daclDefaulted;
  57. ACL_SIZE_INFORMATION aclinfo;
  58. DWORD i;
  59. LPVOID ace;
  60. ACCESS_ALLOWED_ACE* allowace;
  61. ACCESS_DENIED_ACE* denyace;
  62. BOOL allowf=FALSE;
  63. BOOL allowd1=FALSE;
  64. BOOL allowd2=FALSE;
  65. BOOL deny=FALSE;
  66. if(!GetSecurityDescriptorDacl(desc,&daclPresent,&acl,&daclDefaulted)) {
  67.   printerror("Can't read DACL from descriptor for ",file,GetLastError());
  68.   return(TRUE); // Can't read it, don't touch it
  69.   }
  70. if((!daclPresent)||(acl==NULL)) {
  71.   return(TRUE); // No ACL means full access, fine
  72.   }
  73. if(!GetAclInformation(acl,&aclinfo,sizeof(ACL_SIZE_INFORMATION),
  74.    AclSizeInformation)) {
  75.   printerror("Can't read ACL info for ",file,GetLastError());
  76.   return(TRUE);
  77.   }
  78. for(i=0;i<aclinfo.AceCount;i++) {
  79.   if(!GetAce(acl,i,&ace)) {
  80.     printerror("Can't extract ACE from ACL for ",file,GetLastError());
  81.     return(TRUE);
  82.     }
  83.   allowace=(ACCESS_ALLOWED_ACE*) ace;
  84.   denyace=(ACCESS_DENIED_ACE*) ace;
  85.   if(allowace->Header.AceType==ACCESS_ALLOWED_ACE_TYPE) {
  86.     if(EqualSid(adminSid,(SID*)&(allowace)->SidStart)) {
  87.       if(allowace->Mask == (DWORD)0x01f01ff) {
  88.         if(!(allowace->Header.AceFlags & 8)) {
  89.           allowf=TRUE;
  90.           }
  91.         if(allowace->Header.AceFlags & 1) {
  92.           allowd1=TRUE;
  93.           }
  94.         if(allowace->Header.AceFlags & 2) {
  95.           allowd2=TRUE;
  96.           }
  97.         }
  98.       }
  99.     }
  100.   else if(denyace->Header.AceType==ACCESS_DENIED_ACE_TYPE) {
  101.     if(EqualSid(adminSid,(SID*)&(denyace)->SidStart)) {
  102.       deny=TRUE;
  103.       }
  104.     }
  105.   }
  106. if(deny) { return(FALSE); } // Admins explicitly denied
  107. if(isDir && allowd1 && allowd2 && allowf ) { return(TRUE); } // Dir okay
  108. if( (!isDir) && allowf) { return(TRUE); } // File okay
  109. return(FALSE); // Full control ACE's not found
  110. }
  111.  
  112. void AddAdminPerms(WCHAR* file,BOOL isDir)
  113. {
  114. BYTE filebuf[2048];
  115. BYTE sidbuf[1024];
  116. HANDLE fileHandle;
  117. LPVOID context=NULL;
  118. DWORD sizeRead,dummy;
  119. DWORD sidOffset=0x028;
  120. SECURITY_DESCRIPTOR newsd;
  121. SECURITY_DESCRIPTOR newaclsd;
  122. PSECURITY_DESCRIPTOR desc=NULL;
  123. DWORD lastError;
  124. BOOL daclPresent;
  125. PACL acl;
  126. PACL newAcl=NULL;
  127. BOOL daclDefaulted;
  128. ACL_SIZE_INFORMATION aclinfo;
  129. DWORD i,j;
  130. LPVOID ace;
  131. ACCESS_ALLOWED_ACE* allowace;
  132. ACCESS_DENIED_ACE* denyace;
  133. DWORD newAclSize;
  134.  
  135. fileHandle=CreateFile(file,GENERIC_READ,FILE_SHARE_READ,NULL,
  136.              OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
  137. if(fileHandle==INVALID_HANDLE_VALUE) {
  138.   printerror("Can't open file to get owner SID for ",file,GetLastError());
  139.   return;
  140.   }
  141. if(!BackupRead(fileHandle,filebuf,sizeof(filebuf),
  142.    &sizeRead,FALSE,TRUE,&context)) {
  143.   printerror("Can't read file to get owner SID for ",file,GetLastError());
  144.   return;
  145.   }
  146. BackupRead(fileHandle,filebuf,0,&dummy,TRUE,FALSE,&context);
  147. CloseHandle(fileHandle);
  148. if(!IsValidSid((PSID)(filebuf+sidOffset))) {
  149.   printerror("SID Invalid from BackupRead for ",file,GetLastError());
  150.   return;
  151.   }
  152. if(!CopySid(sizeof(sidbuf),(PSID)sidbuf,(PSID)(filebuf+sidOffset))) {
  153.   printerror("SID copy failed for ",file,GetLastError());
  154.   return;
  155.   }
  156.  
  157. if(!SetFileSecurity(file,OWNER_SECURITY_INFORMATION,&adminOwner)) {
  158.   printerror("Can't set owner to Administrators for ",file,GetLastError());
  159.   return;
  160.   }
  161.  
  162. lastError=getFileSecurity(file,&desc);
  163. if(lastError) {
  164.   printerror("Can't get file security for ",file,lastError);
  165.   goto aclupdate_bypass;
  166.   }
  167. if(!GetSecurityDescriptorDacl(desc,&daclPresent,&acl,&daclDefaulted)) {
  168.   printerror("Can't read DACL from descriptor for ",file,GetLastError());
  169.   goto aclupdate_bypass;
  170.   }
  171. if(!daclPresent) {
  172.   printerror("No ACL present for ",file,GetLastError());
  173.   goto aclupdate_bypass;
  174.   }
  175. if(!GetAclInformation(acl,&aclinfo,sizeof(ACL_SIZE_INFORMATION),
  176.    AclSizeInformation)) {
  177.   printerror("Can't read ACL info for ",file,GetLastError());
  178.   goto aclupdate_bypass;
  179.   }
  180. newAclSize=aclinfo.AclBytesInUse;
  181. if(isDir) {
  182.   newAclSize+=dirAllowAce1->Header.AceSize;
  183.   newAclSize+=dirAllowAce2->Header.AceSize;
  184.   }
  185. else {
  186.   newAclSize+=fileAllowAce->Header.AceSize;
  187.   }
  188. newAcl=SafeAlloc(newAclSize);
  189. InitializeAcl(newAcl,newAclSize,ACL_REVISION);
  190. for(i=0,j=0;i<aclinfo.AceCount;i++) {
  191.   if(!GetAce(acl,i,&ace)) {
  192.     printerror("Can't extract ACE from ACL for ",file,GetLastError());
  193.     goto aclupdate_bypass;
  194.     }
  195.   allowace=(ACCESS_ALLOWED_ACE*) ace;
  196.   denyace=(ACCESS_DENIED_ACE*) ace;
  197.   if( (!EqualSid(adminSid,(SID*)&(allowace)->SidStart)) ||
  198.       ( (allowace->Header.AceType!=ACCESS_ALLOWED_ACE_TYPE) &&
  199.         (denyace->Header.AceType!=ACCESS_DENIED_ACE_TYPE) ) ) { 
  200.     if(!AddAce(newAcl,ACL_REVISION,j++,ace,allowace->Header.AceSize)) {
  201.       printerror("Can't add ACE(1) to new ACL for ",file,GetLastError());
  202.       goto aclupdate_bypass;
  203.       }
  204.     }
  205.   }
  206. if(isDir) {
  207.   if(!AddAce(newAcl,ACL_REVISION,j++,dirAllowAce1,
  208.              dirAllowAce1->Header.AceSize)) {
  209.     printerror("Can't add ACE(3) to new ACL for ",file,GetLastError());
  210.     goto aclupdate_bypass;
  211.     }
  212.   if(!AddAce(newAcl,ACL_REVISION,j++,dirAllowAce2,
  213.              dirAllowAce2->Header.AceSize)) {
  214.     printerror("Can't add ACE(4) to new ACL for ",file,GetLastError());
  215.     goto aclupdate_bypass;
  216.     }
  217.   }
  218. else {
  219.   if(!AddAce(newAcl,ACL_REVISION,j++,fileAllowAce,
  220.              fileAllowAce->Header.AceSize)) {
  221.     printerror("Can't add ACE(2) to new ACL for ",file,GetLastError());
  222.     goto aclupdate_bypass;
  223.     }
  224.   }
  225. InitializeSecurityDescriptor(&newaclsd,SECURITY_DESCRIPTOR_REVISION);
  226. if(!SetSecurityDescriptorDacl(&newaclsd,TRUE,newAcl,daclDefaulted)) {
  227.   printerror("Can't put new ACL in SD for ",file,GetLastError());
  228.   goto aclupdate_bypass;
  229.   }
  230. if(!SetFileSecurity(file,DACL_SECURITY_INFORMATION,&newaclsd)) {
  231.   printerror("Can't set new ACL for ",file,GetLastError());
  232.   goto aclupdate_bypass;
  233.   }
  234.  
  235. aclupdate_bypass: 
  236.  
  237. if(desc) LocalFree(desc);
  238. if(newAcl) LocalFree(newAcl);
  239.  
  240. InitializeSecurityDescriptor(&newsd,SECURITY_DESCRIPTOR_REVISION);
  241. if(!SetSecurityDescriptorOwner(&newsd,(PSID)sidbuf,FALSE)) {
  242.   printerror("Can't get old owner security descriptor ",
  243.              file,GetLastError());
  244.   return;
  245.   }
  246. if(!SetFileSecurity(file,OWNER_SECURITY_INFORMATION,&newsd)) {
  247.   printerror("Can't set owner back to original for ",file,GetLastError());
  248.   return;
  249.   }
  250. }
  251.  
  252. void processFile(WCHAR* file,BOOL isDir)
  253. {
  254. PSECURITY_DESCRIPTOR desc=NULL;
  255. DWORD lastError;
  256. lastError=getFileSecurity(file,&desc);
  257. if((lastError)||(!isAclOkay(file,desc,isDir))) {
  258.   printf("%s %S\n",isDir?"dir  ":"file ",file);
  259.   AddAdminPerms(file,isDir);
  260.   }
  261. if(desc) { LocalFree(desc); }
  262. }
  263.  
  264. DWORD getFileSecurity(WCHAR* file,PSECURITY_DESCRIPTOR* desc)
  265. {
  266. DWORD curSize;
  267. DWORD sizeNeeded;
  268. BOOL result;
  269. DWORD lastError;
  270.  
  271. curSize=1024;
  272. for(;;) {
  273.   *desc=SafeAlloc(curSize);
  274.   result=GetFileSecurity(file,DACL_SECURITY_INFORMATION,*desc,
  275.                          curSize,&sizeNeeded);
  276.   if(result) return(NO_ERROR);
  277.   lastError=GetLastError();
  278.   if(lastError == ERROR_INSUFFICIENT_BUFFER) { 
  279.     LocalFree(*desc);
  280.     curSize*=2;
  281.     }
  282.   else {
  283.     return(lastError);
  284.     }
  285.   }
  286. }
  287.  
  288. void recursive_find(WCHAR* searchpath)
  289. {
  290. WIN32_FIND_DATA finddata;
  291. HANDLE h;
  292. WCHAR* fn;
  293. WCHAR findpath[MAX_PATH];
  294. WCHAR filepath[MAX_PATH];
  295. BOOL cont=TRUE;
  296. BOOL isDir;
  297. DWORD errorno;
  298.  
  299. if(GetFileAttributes(searchpath)&FILE_ATTRIBUTE_DIRECTORY) {
  300.   processFile(searchpath,TRUE);
  301.   lstrcpy(findpath,searchpath);
  302.   lstrcat(findpath,BACKSLASH);
  303.   lstrcat(findpath,SDS);
  304.   h=FindFirstFile(findpath,&finddata);
  305.   for(;;) {
  306.     if((h==INVALID_HANDLE_VALUE)||(!cont)) {
  307.       errorno=GetLastError();
  308.       if(errorno!=ERROR_NO_MORE_FILES) {
  309.         printerror("Can't scan directory ",searchpath,errorno);
  310.         }
  311.       break;
  312.       }
  313.     fn=finddata.cFileName;
  314.     isDir=(finddata.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)?TRUE:FALSE;
  315.     if((!lstrcmp(fn,DOT))||(!lstrcmp(fn,DOTDOT))) { goto nextfile; }
  316.     lstrcpy(filepath,searchpath);
  317.     lstrcat(filepath,BACKSLASH);
  318.     lstrcat(filepath,fn);
  319.     processFile(filepath,isDir);
  320.     if(isDir) {
  321.       WCHAR subdir[MAX_PATH];
  322.       lstrcpy(subdir,searchpath);
  323.       lstrcat(subdir,BACKSLASH);
  324.       lstrcat(subdir,fn);
  325.       recursive_find(subdir);
  326.       }
  327.     nextfile:
  328.     cont=FindNextFile(h,&finddata); 
  329.     }
  330.   FindClose(h);
  331.   }
  332. else {
  333.   processFile(searchpath,FALSE);
  334.   }
  335.  
  336. void printerror(char* str,WCHAR* file,DWORD errorno)
  337. {
  338. #define printerrorbufsize 4096
  339. WCHAR buf[printerrorbufsize];
  340. va_list ap;
  341. va_start(ap,errorno);
  342. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,errorno,0,
  343.   buf,printerrorbufsize-1,&ap);
  344. printf("%s%S: %S",str,file,buf);
  345. va_end(ap);
  346. }
  347.  
  348. void setConstants()
  349. {
  350. DWORD sidSize; // ,domSize;
  351. // WCHAR domName[256];
  352. DWORD fileAllowAceSize;
  353. // WCHAR* admins=lmbstowcs("Administrators");
  354. // SID_NAME_USE peUse;
  355. DOT=lmbstowcs(".");
  356. DOTDOT=lmbstowcs("..");
  357. BACKSLASH=lmbstowcs("\\");
  358. SDS=lmbstowcs("*.*");
  359. sidSize=1024;
  360. // domSize=sizeof(domName);
  361. adminSid=SafeAlloc(sidSize);
  362. // if(!LookupAccountName(NULL,admins,adminSid,&sidSize,domName,
  363. //    &domSize,&peUse)) {
  364. //   printerror("Can't get Administrators SID ",(WCHAR*)"",GetLastError());
  365. //   exit(1);
  366. //   }
  367. // LocalFree(admins);
  368. CopyMemory(adminSid,"\001\002\000\000\000\000\000\005\040\000\000\000\040\002\000\000",16);
  369. InitializeSecurityDescriptor(&adminOwner,SECURITY_DESCRIPTOR_REVISION);
  370. if(!SetSecurityDescriptorOwner(&adminOwner,adminSid,FALSE)) {
  371.   printerror("Can't get Administrators Owner security descriptor ",
  372.              (WCHAR*)"",GetLastError());
  373.   exit(1);
  374.   }
  375. fileAllowAceSize=sizeof(ACCESS_ALLOWED_ACE)+GetLengthSid(adminSid);
  376. fileAllowAce=SafeAlloc(fileAllowAceSize);
  377. fileAllowAce->Header.AceType=ACCESS_ALLOWED_ACE_TYPE;
  378. fileAllowAce->Header.AceFlags=0;
  379. fileAllowAce->Header.AceSize=(WORD)fileAllowAceSize;
  380. fileAllowAce->Mask=(DWORD)0x01f01ff;
  381. CopyMemory(&(fileAllowAce->SidStart),adminSid,GetLengthSid(adminSid));
  382. dirAllowAce1=SafeAlloc(fileAllowAceSize);
  383. dirAllowAce2=SafeAlloc(fileAllowAceSize);
  384. CopyMemory(dirAllowAce1,fileAllowAce,fileAllowAceSize);
  385. CopyMemory(dirAllowAce2,fileAllowAce,fileAllowAceSize);
  386. dirAllowAce1->Header.AceFlags=8+1;
  387. dirAllowAce2->Header.AceFlags=2;
  388. }
  389.  
  390. void getPrivs() // Turn on Backup, Restore, and Take Ownership
  391. {
  392. HANDLE h;
  393. LUID takeown;
  394. LUID backup;
  395. LUID restore;
  396. TOKEN_PRIVILEGES privs;
  397. DWORD lastError;
  398. if(!OpenProcessToken(GetCurrentProcess(),
  399.     TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&h)) {
  400.   printerror("Can't get process token ",(WCHAR*)"",GetLastError());
  401.   exit(1);
  402.   }
  403. if(!LookupPrivilegeValue((WCHAR*)NULL,
  404.                     (WCHAR*)SE_TAKE_OWNERSHIP_NAME,&takeown)) {
  405.   printerror("Can't get Take Ownership privilege value ",(WCHAR*)"",
  406.              GetLastError());
  407.   exit(1);
  408.   }
  409. if(!LookupPrivilegeValue((WCHAR*)NULL,(WCHAR*)SE_BACKUP_NAME,&backup)) {
  410.   printerror("Can't get Backup privilege value ",(WCHAR*)"",
  411.              GetLastError());
  412.   exit(1);
  413.   }
  414. if(!LookupPrivilegeValue((WCHAR*)NULL,(WCHAR*)SE_RESTORE_NAME,&restore)) {
  415.   printerror("Can't get Restore privilege value ",(WCHAR*)"",
  416.              GetLastError());
  417.   exit(1);
  418.   }
  419.  
  420. privs.PrivilegeCount=1;
  421. privs.Privileges[0].Luid=takeown;
  422. privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  423. AdjustTokenPrivileges(h,FALSE,&privs,sizeof(TOKEN_PRIVILEGES),
  424.   (PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL);
  425.  
  426. lastError=GetLastError();
  427. if(lastError != NO_ERROR) {
  428.   printerror("Can't set Take Ownership privilege ",(WCHAR*)"",lastError);
  429.   exit(1);
  430.   }
  431.  
  432. privs.PrivilegeCount=1;
  433. privs.Privileges[0].Luid=backup;
  434. privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  435. AdjustTokenPrivileges(h,FALSE,&privs,sizeof(TOKEN_PRIVILEGES),
  436.   (PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL);
  437.  
  438. lastError=GetLastError();
  439. if(lastError != NO_ERROR) {
  440.   printerror("Can't set Backup privilege ",(WCHAR*)"",lastError);
  441.   exit(1);
  442.   }
  443.  
  444. privs.PrivilegeCount=1;
  445. privs.Privileges[0].Luid=restore;
  446. privs.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
  447. AdjustTokenPrivileges(h,FALSE,&privs,sizeof(TOKEN_PRIVILEGES),
  448.   (PTOKEN_PRIVILEGES) NULL,(PDWORD) NULL);
  449.  
  450. lastError=GetLastError();
  451. if(lastError != NO_ERROR) {
  452.   printerror("Can't set Restore privilege ",(WCHAR*)"",lastError);
  453.   exit(1);
  454.   }
  455. }
  456.  
  457. HLOCAL SafeAlloc(UINT bytes)
  458. {
  459. HLOCAL result;
  460. result=LocalAlloc(LPTR,bytes);
  461. if(!result) {
  462.   printerror("Can't allocate memory ",(WCHAR*)"",GetLastError());
  463.   exit(1);
  464.   }
  465. return(result);
  466. }
  467.  
  468. WCHAR *lmbstowcs(char *aname )
  469. {
  470. if (aname) {
  471.   WCHAR *pwname = NULL;
  472.   WCHAR *prwname;
  473.   pwname = (WCHAR *)SafeAlloc(sizeof(WCHAR) * (strlen(aname)+1));
  474.   prwname = pwname;
  475.   for (; *prwname = (WCHAR)(*aname);prwname++,aname++  );
  476.   return(pwname);
  477.   }
  478. else {
  479.   return(NULL);
  480.   }
  481. }
  482.  
  483.